#!/usr/bin/env python
##-----------------------------------------------------------------------------
##  File:   tex_iter.py
##  Author: Jim Storch
##-----------------------------------------------------------------------------

import re
import sys

def line_iter(filename):

    """
    Line Iterator for LaTeX source files.

    Given a LaTeX source file name, iterates through each line of the file
    returning a tuple containing the filename, the current line number, and
    the text of the line with comments stripped.

    If it encounters a line with a "\include" or "\input", it recursively 
    iterates the nested file instead of returning the line.
    """

    ## Regex to match comments
    re_comment = r"""([^\\]|^)\%.*$"""

    ## Regex to match include files
    re_include = r"""\\include\{(?P<filename>.[^}]+)\}"""
    
    ## Regex to match input files
    re_input = r"""\\input\{(?P<filename>.[^}]+)\}"""

    try:
        fp = open(filename, 'r')
    except IOError:
        print "ERROR: Unable to open the file '%s'" % filename
        sys.exit(1)


    for number, line in enumerate(fp):

        ## Strip any comments
        line = re.sub(re_comment, '', line.strip())

        ## Look for nested tex files
        include_file = re.search(re_include, line)
        input_file = re.search(re_input, line)


        if include_file:
            nested = include_file.group('filename')
            for tup in line_iter(nested):
                yield tup
  
        elif input_file:
            nested = input_file.group('filename')
            for tup in line_iter(nested):
                yield tup

        else:
            yield(filename, number, line)



def word_iter(filename):

    """
    Word Iterator for LaTeX source files.

    Given a LaTeX source file name, iterates through each word of the file
    returning a tuple containing the filename, the current line number, the 
    current word number (of that line) and a word.
    """
        

    for filename, line_number, line in line_iter(filename):
        words = line.split()
        for word_number, word in enumerate(words):
            yield(filename, line_number, word_number, word)
    

